<template>
  <div class="mb-4">
    <section
      v-if="operateType !== 'add' && operateType !== 'edit'"
      class="toggle my-3 mx-4 text-center primary--text rounded-md-l"
      @click="goTo({ name: 'user', query: $route.query }, true)"
    >
      切换就诊人
    </section>
    <van-form ref="userInfo" @submit="onSubmit">
      <component
        :is="item.componentId"
        v-for="(item, index) in patientInfos"
        :key="item.code"
        :prop-item="item"
        :class="{ 'mt-2': index % 4 === 0 }"
        @accept="handleAccept"
      ></component>
      <footer class="mt-12 px-10">
        <field-item-button
          v-for="item in buttonGroup"
          v-show="calcShowButton(item.show)"
          :key="item.buttonText"
          :prop="item"
          @accept="handleButton"
        ></field-item-button>
      </footer>
    </van-form>
  </div>
</template>
<script>
import { fieldItemInput, fieldItemPicker, fieldItemRadio, fieldItemDate, fieldItemButton } from '@/components';
import { idValidator, phoneValidator } from '@/utils/validator';
import { patientInfos, buttonGroup } from './utils/config';

export default {
  name: 'AddEditUser',
  components: {
    fieldItemInput,
    fieldItemPicker,
    fieldItemRadio,
    fieldItemDate,
    fieldItemButton,
  },
  head() {
    const title = {
      add: '添加就诊人',
      edit: '编辑就诊人',
      chose: '选择就诊人',
    };
    return {
      title: title[this.operateType],
    };
  },
  async asyncData({ query: { operateType, id }, $lvtongApis }) {
    let defaultPatient = {};
    if (operateType !== 'add') {
      try {
        defaultPatient = await $lvtongApis.getDefaultPatient({ catchError: false }).then(({ data }) => data || {});
      } catch {
        // FIXME: 默认不存在时用补充信息，其它要提示异常，目前code区分不出
        // ate by dog
      }
    }

    return {
      defaultPatient,
      hasDefaultPatient: !!Object.keys(defaultPatient).length,
      operateType,
      id,
    };
  },
  data() {
    return {
      operateType: 'chose',
      patient: {},
      patientInfosResult: patientInfos(),
      patientInfos: [],
      buttonGroup,
      defaultPatient: {},
      hasDefaultPatient: false,
    };
  },
  computed: {
    calcShowButton() {
      return (arr) => {
        return arr.includes(this.operateType);
      };
    },
  },
  mounted() {
    this.assignDefaultPatient();
  },
  methods: {
    assignDefaultPatient() {
      if (this.hasDefaultPatient) {
        this.patientInfos = this.patientInfosResult.map((item) => {
          this.patient[item.code] = this.defaultPatient[item.code];
          return { ...item, value: this.defaultPatient[item.code] };
        });
      } else {
        this.patientInfos = this.patientInfosResult;
      }
    },
    handleAccept(item) {
      this.patient[item.code] = item.value;
      if (item.code === 'patientCardNo' && this.patient.patientCardType === 10401) {
        this.handleSpecialTrans();
      }
    },
    handleSpecialTrans() {
      const info = idValidator.getInfo(this.patient.patientCardNo);
      if (info) {
        this.patientInfos = this.patientInfos.map((item) => {
          if (item.code === 'patientGender') {
            return {
              ...item,
              value: info.sex ? 10901 : 10902,
            };
          } else if (item.code === 'patientBirthdate') {
            return {
              ...item,
              value: info.birth,
            };
          } else {
            return item;
          }
        });
      } else {
        this.$toast('证件号码不正确');
      }
    },
    handleButton({ funcName, funcArguments }) {
      if (typeof this[funcName] === 'function') {
        this[funcName](funcArguments);
      }
    },
    addpatient() {
      this.$refs.userInfo.validate().then(async () => {
        const success = this.validator();
        if (success) {
          await this.$$lvtongApis.addPatient({ data: this.patient, loading: true });
          this.goTo({ name: 'user', query: this.$route.query }, true);
        }
      });
    },
    async onSubmit() {
      const success = this.validator();
      if (success) {
        if (this.hasDefaultPatient) {
          // 如果能查到默认值使用默认就诊人
          await this.$$lvtongApis.modifyPatient({
            data: { ...this.patient, patientId: this.defaultPatient.patientId },
            loading: true,
          });
        } else {
          // 如果查不到默认应新增,并设为默认
          const patientId = await this.$$lvtongApis
            .addPatient({ data: this.patient, loading: true })
            .then(({ data }) => data);
          await this.$$lvtongApis.chosePatient(patientId)({ loading: true });
        }
        this.goTo({ name: 'choose-service', query: this.$route.query });
      }
    },
    validator() {
      const { patientCardType, patientCardNo, patientGender, patientBirthdate, medicareMobile } = this.patient;
      // 需单独校验身份证的号码是否正确
      if (patientCardType === 10401) {
        if (patientCardNo && !idValidator.isValid(patientCardNo)) {
          this.$toast('证件号码不正确');
          return false;
        }
        // 校验出生日期及性别与身份证输入是否一致
        if (patientGender) {
          const { sex } = idValidator.getInfo(patientCardNo);
          if ((sex === 1 && patientGender === 10902) || (sex === 0 && patientGender === 10901)) {
            this.$toast('所选性别与证件号码不一致');
            return false;
          }
        }
        if (patientBirthdate) {
          const { birth } = idValidator.getInfo(patientCardNo);
          if (birth !== patientBirthdate) {
            this.$toast('所选出生日期与证件号码不一致');
            return false;
          }
        }
      }
      // 医保手机非必填，填写后校验
      if (medicareMobile && !phoneValidator(medicareMobile)) {
        this.$toast('医保手机不正确');
        return false;
      }
      return true;
    },
    deleteUser() {
      this.$dialog
        .confirm({
          title: '删除就诊人',
          message: '确认删除？',
        })
        .then(async () => {
          await this.$$lvtongApis
            .delPatient(this.defaultPatient.patientId)({ loading: true })
            .then((_) => {
              this.goTo({ name: 'user' }, true);
            });
        })
        .catch(() => {});
    },
  },
};
</script>
<style scoped lang="less">
.toggle {
  line-height: 48px;
  box-shadow: 0px 1px 10px 0px rgba(198, 202, 211, 0.4);
}
</style>
